/*************************************************************************
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: IBM Corporation
 *
 *  Copyright: 2008 by IBM Corporation
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/*************************************************************************
 * @file 
 *  For LWP filter architecture prototype
 ************************************************************************/
/*************************************************************************
 * Change History
 Jan 2005			Created
 ************************************************************************/
 
#include "lwpfribptr.hxx"

#include "lwpfribheader.hxx"
#include "lwpfribtext.hxx"
#include "lwppara.hxx"
#include "lwpstory.hxx"
#include "xfilter/xftextspan.hxx"
#include "xfilter/xftextcontent.hxx"
#include "xfilter/xftabstop.hxx"
#include "xfilter/xflinebreak.hxx"
#include "lwpfribsection.hxx"
#include "lwpsection.hxx"
#include "lwpfribbreaks.hxx"
#include "lwpfribframe.hxx"
#include "lwpfribtable.hxx"
#include "xfilter/xfstylemanager.hxx"
#include "lwphyperlinkmgr.hxx"
#include "xfilter/xfhyperlink.hxx"
#include "lwpfootnote.hxx"
#include "lwpnotes.hxx"
#include "lwpfribmark.hxx"
#include "xfilter/xfchange.hxx"
#include "lwpchangemgr.hxx"
#include "lwpglobalmgr.hxx"


LwpFribPtr::LwpFribPtr()
	: m_pFribs(NULL),m_pPara(NULL),m_pXFPara(NULL)
{}

LwpFribPtr::~LwpFribPtr()
{
	LwpFrib* pNextFrib = m_pFribs;
	LwpFrib* pCurFrib = m_pFribs;
	while(pCurFrib)
	{
		pNextFrib = pCurFrib -> GetNext();
		delete pCurFrib;
		pCurFrib = pNextFrib;
	}
}

void LwpFribPtr::ReadPara(LwpObjectStream* pObjStrm)
{
	sal_uInt8 FribTag=0;
	sal_uInt8 FribType;
	sal_uInt8 FribEditor;
	BOOL ProblemFrib;

	LwpFrib* pCurFrib = m_pFribs = NULL;
	for(;;)
	{
		ProblemFrib = FALSE;
		// Get the frib type
		pObjStrm->QuickRead(&FribTag, sizeof(FribTag));

		FribType = FribTag & ~FRIB_TAG_TYPEMASK;
		
		// Stop when we hit Elvis
		if (FribType == FRIB_TAG_ELVIS)
			break;

		// skip the editor ID
		//pObjStrm->SeekRel(sizeof(sal_uInt8));
 		pObjStrm->QuickRead(&FribEditor, sizeof(FribEditor));
		if( FribType != FT_MAXIMUM )
		{
			LwpFrib* pFrib = LwpFrib::CreateFrib( m_pPara, pObjStrm, FribTag,FribEditor);
			if(!m_pFribs)
			{
				m_pFribs = pFrib;
			}
			if(pCurFrib)
			{
				pCurFrib->SetNext(pFrib);
			}
			else//frist frib in the para,add by  2/1
			{
				if (pFrib->GetType() == FRIB_TAG_TEXT)
				{
					LwpFribText* pText = static_cast<LwpFribText*>(pFrib);
					if (pFrib->GetModifiers())
						m_pPara->SetFirstFrib(pText->GetText(),pText->GetModifiers()->FontID);
					else
						m_pPara->SetFirstFrib(pText->GetText(),0);					
				}
			}
			pCurFrib = pFrib;
		}
		else
			ProblemFrib = TRUE;
	}
}

/*String LwpFribPtr::GetText()
{
	LwpFrib* pFrib = m_pFribs;
	String content;
	while(pFrib)
	{
		if(pFrib->GetType() == FRIB_TAG_TEXT)
		{
			content+= static_cast<LwpFribText*>(pFrib)->GetText();	
		}
		pFrib = pFrib->GetNext();
	}
	return (content);
}*/

#include "lwpdropcapmgr.hxx"
void LwpFribPtr::XFConvert()
{  	            
	LwpFrib* pFrib = m_pFribs;
	while(pFrib)
	{
		sal_uInt8 nFribType = pFrib->GetType();
		sal_Bool bRevisionFlag = pFrib->GetRevisionFlag();
		sal_uInt8 nRevisionType;
		OUString sChangeID;
		if (bRevisionFlag)
		{
			if ( nFribType!= FRIB_TAG_TABLE && nFribType != FRIB_TAG_FIELD 
					&& nFribType != FRIB_TAG_FRAME)
			{
				nRevisionType = pFrib->GetRevisionType();
				LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance(); 
				LwpChangeMgr* pChangeMgr = pGlobal->GetLwpChangeMgr();
				sChangeID = pChangeMgr->GetChangeID(pFrib);
				if (sChangeID.getLength())
				{	
				///	if (nRevisionType == LwpFrib::REV_INSERT)
				///	{
						XFChangeStart* pChangeStart = new XFChangeStart;
						pChangeStart->SetChangeID(sChangeID);
						m_pXFPara->Add(pChangeStart);
				///	}
				///	else if (nRevisionType == LwpFrib::REV_DELETE)
				///	{
				///		XFChange* pChange = new XFChange;
				///		pChange->SetChangeID(sChangeID);
				///		m_pXFPara->Add(pChange);
				///		pFrib = pFrib->GetNext();
				///		continue;
				///	}
				}
			}
		}
	
        	switch(nFribType)
        	{
		case FRIB_TAG_TEXT:
		{
			LwpFribText* textFrib= static_cast<LwpFribText*>(pFrib);
			textFrib->XFConvert(m_pXFPara,m_pPara->GetStory());
		}
		    break;
		case FRIB_TAG_TAB:
		{
			LwpFribTab* tabFrib = static_cast<LwpFribTab*>(pFrib);
			if (pFrib->m_ModFlag)
			{	
				XFTextSpan *pSpan = new XFTextSpan();
				pSpan->SetStyleName(tabFrib->GetStyleName());
				XFTabStop *pTab = new XFTabStop();
				pSpan->Add(pTab);               
				m_pXFPara->Add(pSpan); 
			}    
			else
			{
				XFTabStop *pTab = new XFTabStop();
				m_pXFPara->Add(pTab);               
			}	
		}	    
		    break;
		case FRIB_TAG_SECTION:
		{
			LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);			
			pSectionFrib->ParseSection();	
		}
		break;

		case FRIB_TAG_PAGEBREAK:
		{
			LwpFribPageBreak* pPageBreak = static_cast<LwpFribPageBreak*>(pFrib);
			LwpPageLayout* pLayout = static_cast<LwpPageLayout*>(pPageBreak->GetLayout()->obj());
			if(pLayout)
			{							
				pPageBreak->ParseLayout();
			}
			else
			{
				if (pPageBreak->IsLastFrib() == sal_True)
				{
					m_pXFPara->SetStyleName( pPageBreak->GetStyleName() );
				}
				else
				{
					//parse pagebreak
					XFParagraph *pPara = new XFParagraph();
					pPara->SetStyleName(pFrib->GetStyleName());	
					SetXFPara(pPara);
					m_pPara->AddXFContent(pPara);
				}
			}		
		}
			break;
		case FRIB_TAG_COLBREAK:
		{
			XFParagraph *pPara = new XFParagraph();
			pPara->SetStyleName(pFrib->GetStyleName());	
			SetXFPara(pPara);
			m_pPara->AddXFContent(pPara);
		}
			break;	
		case FRIB_TAG_LINEBREAK:
		{
			XFLineBreak *pLineBreak = new XFLineBreak();
			m_pXFPara->Add(pLineBreak);  			
		}
			break;	
		case FRIB_TAG_UNICODE: //fall through
		case FRIB_TAG_UNICODE2: //fall through
		case FRIB_TAG_UNICODE3: //fall through
		{
			LwpFribUnicode* unicodeFrib= static_cast<LwpFribUnicode*>(pFrib);
			unicodeFrib->XFConvert(m_pXFPara,m_pPara->GetStory());
		}
			break;
		case FRIB_TAG_HARDSPACE:
		{
			rtl::OUString sHardSpace(sal_Unicode(0x00a0));
			LwpHyperlinkMgr* pHyperlink = 
					m_pPara->GetStory()->GetHyperlinkMgr();
			if (pHyperlink->GetHyperlinkFlag())
				pFrib->ConvertHyperLink(m_pXFPara,pHyperlink,sHardSpace);
			else
				pFrib->ConvertChars(m_pXFPara,sHardSpace);
		}
			break;
		case FRIB_TAG_SOFTHYPHEN:
		{
			rtl::OUString sSoftHyphen(sal_Unicode(0x00ad));
			pFrib->ConvertChars(m_pXFPara,sSoftHyphen);
		}
			break;
		case FRIB_TAG_FRAME:
		{
			LwpFribFrame* frameFrib= static_cast<LwpFribFrame*>(pFrib);
			LwpObject* pLayout = frameFrib->GetLayout();
			if (pLayout->GetTag() == VO_DROPCAPLAYOUT)
			{
				m_pPara->GetFoundry()->GetDropcapMgr()->SetXFPara(m_pXFPara); 
				//LwpObject* pDropCap = frameFrib->GetLayout();
				//pDropCap ->XFConvert(m_pXFPara);
			}
			//pLayout->XFConvert(m_pXFPara);
			frameFrib->XFConvert(m_pXFPara);
		}
			break;
		case FRIB_TAG_CHBLOCK:
		{
			LwpFribCHBlock* chbFrib = static_cast<LwpFribCHBlock*>(pFrib);
			chbFrib->XFConvert(m_pXFPara,m_pPara->GetStory());
		}
			break;
		case FRIB_TAG_TABLE:
		{
			LwpFribTable* tableFrib = static_cast<LwpFribTable*>(pFrib);
			//tableFrib->XFConvert(m_pPara->GetXFContainer());
			tableFrib->XFConvert(m_pXFPara);
		}
			break;
		case FRIB_TAG_BOOKMARK:
		{
			LwpFribBookMark* bookmarkFrib = static_cast<LwpFribBookMark*>(pFrib);
			bookmarkFrib->XFConvert(m_pXFPara);
		}
		break;	
		case FRIB_TAG_FOOTNOTE:
		{			
			LwpFribFootnote* pFootnoteFrib = static_cast<LwpFribFootnote*>(pFrib);
			pFootnoteFrib->XFConvert(m_pXFPara); 
			break;
		}
		case FRIB_TAG_FIELD:
		{
			LwpFribField* fieldFrib = static_cast<LwpFribField*>(pFrib);
			fieldFrib->XFConvert(m_pXFPara); 		
			break;
		}
		case FRIB_TAG_NOTE:
		{
			LwpFribNote* pNoteFrib = static_cast<LwpFribNote*>(pFrib);
			pNoteFrib->XFConvert(m_pXFPara); 
			break;
		}
		case FRIB_TAG_PAGENUMBER:
		{
			LwpFribPageNumber* pagenumFrib = static_cast<LwpFribPageNumber*>(pFrib);
			pagenumFrib->XFConvert(m_pXFPara); 
			break;
		}
		case FRIB_TAG_DOCVAR:
		{
			LwpFribDocVar* docFrib = static_cast<LwpFribDocVar*>(pFrib);
			docFrib->XFConvert(m_pXFPara); 
			break;
		}
		case FRIB_TAG_RUBYMARKER:
		{
			LwpFribRubyMarker* rubyFrib = static_cast<LwpFribRubyMarker*>(pFrib);
			rubyFrib->XFConvert(m_pXFPara); 
			break;
		}
		case FRIB_TAG_RUBYFRAME:
		{
			LwpFribRubyFrame* rubyfrmeFrib = static_cast<LwpFribRubyFrame*>(pFrib);
			rubyfrmeFrib->XFConvert(m_pXFPara); 
			break;
		}
		default :
			break;
		}

		if (bRevisionFlag )//&& pFrib->GetRevisionType() == LwpFrib::REV_INSERT)
		{
			if (nFribType!= FRIB_TAG_TABLE && nFribType != FRIB_TAG_FIELD 
					&& nFribType != FRIB_TAG_FRAME)
			{
				if (sChangeID.getLength())
				{
					XFChangeEnd* pChangeEnd = new XFChangeEnd;
					pChangeEnd->SetChangeID(sChangeID);
					m_pXFPara->Add(pChangeEnd);
				}
			}
		}		
		pFrib = pFrib->GetNext();
	}

}

void LwpFribPtr::FindLayouts()
{
	LwpFrib* pFrib = m_pFribs;
	while(pFrib)
	{
		switch(pFrib->GetType())
        {
			case FRIB_TAG_SECTION:
			{
				LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);
				LwpSection* pSection = pSectionFrib->GetSection();				
				if(pSection)
				{
					LwpPageLayout* pLayout = pSection->GetPageLayout();
					if(pLayout)
					{
						LwpLayout::UseWhenType eSectionType = pLayout->GetUseWhenType();
						if(eSectionType==LwpLayout::StartWithinColume)
						{
							//StartWithinColume type not support now
							break;
						}
						LwpStory* pStory = static_cast<LwpStory*>(m_pPara->GetStoryID()->obj());
						pStory->AddPageLayout(pSection->GetPageLayout());
					}
				}
				
				break;
			}
			case FRIB_TAG_PAGEBREAK:
			{
				LwpFribPageBreak* pPageBreak = static_cast<LwpFribPageBreak*>(pFrib);
				LwpPageLayout* pLayout = static_cast<LwpPageLayout*>(pPageBreak->GetLayout()->obj());
				if(pLayout)
				{
					LwpStory* pStory = static_cast<LwpStory*>(m_pPara->GetStoryID()->obj());
					pStory->AddPageLayout(pLayout);
				}
				break;
			}
			default:
				break;
		}
		pFrib = pFrib->GetNext();
	}
}
/**************************************************************************
 * @descr:  Whether has a frib which type is nType
 * @param:   
 * @param:   
 * @return:  
**************************************************************************/
LwpFrib* LwpFribPtr::HasFrib(sal_uInt8 nType)
{
	LwpFrib* pFrib = m_pFribs;
	while(pFrib)
	{
		if(pFrib->GetType()==nType)
		{
			return pFrib;
		}
		pFrib = pFrib->GetNext();
	}
	return NULL;
}

void LwpFribPtr::GatherAllText()
{
	LwpFrib* pFrib = m_pFribs;
	while(pFrib)
	{
        switch(pFrib->GetType())
        {
		case FRIB_TAG_TEXT:
		{
			OUString sText = static_cast<LwpFribText*>(pFrib)->GetText();
			m_pPara->SetAllText(sText);
			break;
		}
		case FRIB_TAG_UNICODE: //fall through
		case FRIB_TAG_UNICODE2: //fall through
		case FRIB_TAG_UNICODE3: //fall through	:
		{
			OUString sText = static_cast<LwpFribText*>(pFrib)->GetText();
			m_pPara->SetAllText(sText);	
			break;
		}
		default :
			break;
	}		
		pFrib = pFrib->GetNext();	
	}
}

void LwpFribPtr::RegisterStyle()
{ 
	LwpFrib* pFrib = m_pFribs;
	while(pFrib)
	{
        switch(pFrib->GetType())
        {
		case FRIB_TAG_TEXT:
		{
			pFrib->RegisterStyle(m_pPara->GetFoundry());
			OUString sText = static_cast<LwpFribText*>(pFrib)->GetText();
			ProcessDropcap(m_pPara->GetStory(), pFrib,sText.getLength());
			break;
		}
		case FRIB_TAG_TAB:
			pFrib->RegisterStyle(m_pPara->GetFoundry());		
		    break;
		case FRIB_TAG_SECTION:
			{
				//section registerstyle here;
				LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);
				pSectionFrib->RegisterSectionStyle();
				//for bullet
				pSectionFrib->SetSectionName();				
			}			
			break;
		case FRIB_TAG_PAGEBREAK:
		{
			LwpFribPageBreak* breakFrib = static_cast<LwpFribPageBreak*>(pFrib);
			breakFrib->RegisterBreakStyle(m_pPara);
		}	
			break;
		case FRIB_TAG_COLBREAK:
		{
			LwpFribColumnBreak* breakFrib = static_cast<LwpFribColumnBreak*>(pFrib);
			breakFrib->RegisterBreakStyle(m_pPara);				
		}
			break;
		case FRIB_TAG_UNICODE: //fall through
		case FRIB_TAG_UNICODE2: //fall through
		case FRIB_TAG_UNICODE3: //fall through	:
		{
			pFrib->RegisterStyle(m_pPara->GetFoundry());	
			OUString sText = static_cast<LwpFribUnicode*>(pFrib)->GetText();
			ProcessDropcap(m_pPara->GetStory(), pFrib,sText.getLength());	
		    break;
		}
		case FRIB_TAG_HARDSPACE:
			pFrib->RegisterStyle(m_pPara->GetFoundry());
			ProcessDropcap(m_pPara->GetStory(),pFrib,1);			
			break;
		case FRIB_TAG_SOFTHYPHEN:
			pFrib->RegisterStyle(m_pPara->GetFoundry());
			break;
		case FRIB_TAG_FRAME:
		{
			LwpFribFrame* frameFrib = static_cast<LwpFribFrame*>(pFrib);
			frameFrib->SetParaDropcap(m_pPara); 
			frameFrib->RegisterStyle(m_pPara->GetFoundry());
			//register framelayout style, ,03/09/2005
			//frameFrib->GetLayout()->RegisterStyle();
                }
                	break;  
                case FRIB_TAG_CHBLOCK:
                	break;
                case FRIB_TAG_TABLE:
                {
                	LwpFribTable* tableFrib = static_cast<LwpFribTable*>(pFrib);
                	tableFrib->RegisterStyle();
                }
                	break;
		case FRIB_TAG_FOOTNOTE:	
		{
			LwpFribFootnote* pFribFootnote = static_cast<LwpFribFootnote*>(pFrib);
			pFribFootnote->RegisterStyle();
		}					
			break;
		case FRIB_TAG_NOTE:
		{
			LwpFribNote* pNoteFrib = static_cast<LwpFribNote*>(pFrib);
			pNoteFrib->RegisterStyle(); 
			break;
		}
		case FRIB_TAG_PAGENUMBER:
		{
			pFrib->RegisterStyle(m_pPara->GetFoundry());
			break;
		}
		case FRIB_TAG_DOCVAR:
		{
			LwpFribDocVar* docFrib = static_cast<LwpFribDocVar*>(pFrib);
			docFrib->RegisterStyle(m_pPara->GetFoundry()); 
			break;
		}
		case FRIB_TAG_FIELD:
		{
			LwpFribField* fieldFrib = static_cast<LwpFribField*>(pFrib);
			fieldFrib->RegisterStyle(m_pPara->GetFoundry());  		
			break;
		}
		case FRIB_TAG_BOOKMARK:
		{
			LwpFribBookMark* bookmarkFrib = static_cast<LwpFribBookMark*>(pFrib);
			bookmarkFrib->RegisterStyle(m_pPara->GetFoundry());			
			break;
		}
		case FRIB_TAG_RUBYFRAME:
		{
			LwpFribRubyFrame* rubyfrmeFrib = static_cast<LwpFribRubyFrame*>(pFrib);
			rubyfrmeFrib->RegisterStyle(m_pPara->GetFoundry()); 
			break;
		}
		default :
			break;
		}
		if (pFrib->GetRevisionFlag() && pFrib->GetType()!= FRIB_TAG_FIELD)
		{
			LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance(); 
			LwpChangeMgr* pChangeMgr = pGlobal->GetLwpChangeMgr();
			pChangeMgr->AddChangeFrib(pFrib);
		}
			
		pFrib = pFrib->GetNext();
	}
}

void LwpFribPtr::ProcessDropcap(LwpStory* pStory,LwpFrib* pFrib,sal_uInt32 nLen)
{
	if (pStory)
	{
		if (pStory->GetDropcapFlag() == sal_True)
		{
			XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
			XFTextStyle* pFribStyle = pXFStyleManager->FindTextStyle(pFrib->GetStyleName());
			pFribStyle->GetFont()->SetFontSize(0);

			LwpObject*  pObj= pStory->GetLayoutsWithMe()->GetOnlyLayout()->obj();
			if (pObj)
				static_cast<LwpDropcapLayout*>(pObj)->SetChars(nLen);
		}		
	}
}
/**
 * @descr:  If the position of pPreLayout is earlier than pNextLayout, return true, or return false, defalut return true
 * 
*/
sal_Bool LwpFribPtr::ComparePagePosition(LwpVirtualLayout* pPreLayout, LwpVirtualLayout* pNextLayout)
{
	if(!pPreLayout || !pNextLayout)
		return sal_True;
	
	LwpFrib* pFrib = m_pFribs;
	LwpVirtualLayout* pLayout = NULL;
	while(pFrib)
	{
		switch(pFrib->GetType())
        	{
			case FRIB_TAG_SECTION:
			{
				LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);
				LwpSection* pSection = pSectionFrib->GetSection();				
				if(pSection)
				{
					pLayout = pSection->GetPageLayout();
				}
				
				break;
			}
			case FRIB_TAG_PAGEBREAK:
			{
				LwpFribPageBreak* pPageBreak = static_cast<LwpFribPageBreak*>(pFrib);				
				pLayout = static_cast<LwpVirtualLayout*>(pPageBreak->GetLayout()->obj());				
				break;
			}
			default:
				break;
		}

		if(pLayout)
		{
			if(pPreLayout == pLayout)
				return sal_True;
			if(pNextLayout == pLayout)
				return sal_False;
		}				
		pFrib = pFrib->GetNext();
	}

	return sal_True;
}
